#pragma once
#include "mysql.hpp"
#include "message.hxx"
#include "message-odb.hxx"

namespace xchat
{
class MessageTable
{
public:
    using ptr = std::shared_ptr<MessageTable>;

    MessageTable(const std::shared_ptr<odb::core::database>& db) 
        : _db(db) {}
    ~MessageTable() {}
    //新增一条数据
    bool insert(Message &msg)
    {
        try
        {
            odb::transaction trans(_db->begin());
            _db->persist(msg);
            trans.commit();
        }catch(std::exception &e){
            LOG_ERROR("新增消息失败 {} : {}", msg.message_id(), e.what());
            return false;
        }
        return true;
    }
    //删除数据 删除好友退出群聊
    bool remove(const std::string &ssid)
    {
        try
        {
            odb::transaction trans(_db->begin());
            typedef odb::query<Message> query;
            typedef odb::result<Message> result;
            _db->erase_query<Message>(query::session_id == ssid);

            trans.commit();
        }
        catch(std::exception &e){
            LOG_ERROR("删除会话所有消息失败{} : {}", ssid, e.what());
            return false;
        }
        return true;
    }
    //获取最近的几条消息
    std::vector<Message> recent(const std::string &ssid, int64_t count)
    {
        std::vector<Message> res;
        try
        {   //开启事务
            odb::transaction trans(_db->begin());
            typedef odb::query<Message> query;
            typedef odb::result<Message> result;
            //以ssid 为过滤条件 然后以时间逆序排序
            std::stringstream condition;
            condition << "session_id = '" << ssid << "' order by create_time desc limit " << count;
            result r(_db->query<Message>(condition.str()));
            for (const auto &it : r)
            {
                res.push_back(it);
            }
            //提交事务
            trans.commit();
        }catch(std::exception &e){
            LOG_ERROR("获取最近的几条消息失败{}-{}-{}", ssid, count, e.what());
        }
        std::reverse(res.begin(), res.end());
        return res;
    }
    //获取指定时间段内的所有消息 
    std::vector<Message> range(const std::string &ssid, 
                boost::posix_time::ptime &start_time, boost::posix_time::ptime &end_time)
    {
        std::vector<Message> res;
        try
        { //开启事务
            odb::transaction trans(_db->begin());
            typedef odb::query<Message> query;
            typedef odb::result<Message> result;
            //以ssid 为过滤条件 然后以时间逆序排序
            result r(_db->query<Message>(query::session_id == ssid && query::create_time >= start_time && query::create_time <= end_time));
            for (const auto &it : r)
            {
                res.push_back(it);
            }
        //提交事务
        trans.commit();
        }catch(std::exception &e){
            LOG_ERROR("获取区间消息失败{}-{}:{}-{}", ssid, 
                boost::posix_time::to_simple_string(start_time), boost::posix_time::to_simple_string(end_time), e.what());
        }
        return res;
    }

private:
    std::shared_ptr<odb::core::database> _db;

};

}